package com.qiyun.asyncarrange;
//221
import java.util.concurrent.*;

public class CompletableFutureTest06 {

    public static ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
            200,
            10,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(100000),
            Executors.defaultThreadFactory(),//默认线程工厂
            new ThreadPoolExecutor.AbortPolicy()//拒绝策略
            //如果不想抛弃还要执行。可以使用new ThreadPoolExecutor.CallerRunsPolicy()
    );

    /**
     * 线程串行化
     *
     * @param args
     */
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        /**
         *  public <U> CompletableFuture<U> applyToEither(CompletionStage<? extends T> other,Function<? super T, U> fn)
         *  public <U> CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other,Function<? super T, U> fn)
         *  public <U> CompletableFuture<U> applyToEitherAsync(CompletionStage<? extends T> other,Function<? super T, U> fn,Executor executor)
         *
         *
         *  public CompletableFuture<Void> acceptEither(CompletionStage<? extends T> other,Consumer<? super T> action)
         *  public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other,Consumer<? super T> action)
         *  public CompletableFuture<Void> acceptEitherAsync(CompletionStage<? extends T> other,Consumer<? super T> action,Executor executor)
         *
         *
         *  public CompletableFuture<Void> runAfterEither(CompletionStage<?> other,Runnable action)
         *  public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,Runnable action)
         *  public CompletableFuture<Void> runAfterEitherAsync(CompletionStage<?> other,Runnable action,Executor executor)
         *
         *
         */


            /*

              1. 两个都完成

             */
        CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务1线程" + Thread.currentThread().getId() + ",执行。。。");
            int i = 10 / 3;
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务1线程运行结果..." + i);
            return i;
        }, executor);
        CompletableFuture<Integer> future02 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2线程" + Thread.currentThread().getId() + ",执行。。。");
            int i = 10 / 2;
            /*try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
            System.out.println("任务2线程运行结果..." + i);

            return i;
        }, executor);


        /*
             runAfterEither：两个任务有一个执行完成，不需要获取future的结果，处理任务，也没有返回值。
         */
       /* future01.runAfterEitherAsync(future02, () -> {
             System.out.println("任务3线程开始执行");
        }, executor);*/


         /*
             acceptEither：两个任务有一个执行完成，获取它的返回值，处理任务，没有新的返回值。
             future01,future02的返回值类型必须相同，否则任务3不知道该用那个类型接收，
                当然我们可以把future01,future02的返回值类型改为object
             future03任务三拿到的结果，可能的任务1(future01)的运行结果，也有可能是任务2(future02)的结果，
             future03任务三拿到的结果，拿的是先执行完成的任务的结果
         */
/*       future01.acceptEitherAsync(future02, (res) -> {
            System.out.println("任务3线程开始执行之前，拿到的结果"+res);
        }, executor);

        System.out.println("main...end...");*/






        /*
             applyToEither：两个任务有一个执行完成，获取它的返回值，处理任务并有新的返回值。
         */
       CompletableFuture<String> future = future01.applyToEitherAsync(future02, (res) -> {
            System.out.println("任务3线程开始执行之前，拿到的结果" + res);
            return res.toString() + "->哈哈";
        }, executor);
        System.out.println("任务3的返回结果->" + future.get());
        System.out.println("main...end...");

    }

}
